#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTextStream>
#include <QProcess>
#include <QColorDialog>
#include <QFileDialog>
#include <QPoint>
#include <QThread>

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    path_of_opened_file = "";
    QObject::connect(ui->Button_Create_World, SIGNAL(clicked()),this,SLOT(Button_Create_World_Function()));
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::setOS(QString init_OS)
{
    OS = init_OS;
}
World MainWindow::return_Prog_World()
{
    return Prog_World;
}
void MainWindow::Button_Create_World_Function()
{
    ui->Combo_Box_GO->clear();
    ui->Combo_Box_Zones->clear();
    ui->World_Information_Text->clear();
    ui->GO_Information_Text->clear();
    ui->Zone_Information_Text->clear();
    Create_World_Function(ui->Entering_Text->toPlainText());
    GOs_Combo_Box_Initialization();
    GOs_Notes_Initialization();
    QString path_of_svg_file;
    path_of_svg_file = QFileDialog::getSaveFileName(this, "Save svg file", ".", "svg files *.svg;;");
    Prog_World.Drawing_World(path_of_svg_file);
}
void MainWindow::Create_World_Function(QString Description_Of_World)
{
    World New_World;

    QFile input_bison_file("./Input.txt");
    input_bison_file.open(QIODevice::WriteOnly);

    QTextStream out(&input_bison_file);
    out.setCodec("Windows-1251");
    out << Description_Of_World; //скинули в промежуточный файл текст для обработки
    input_bison_file.close();

    QFile output_bison_file("./Output.txt"); // создания файла для информации о карте
    output_bison_file.open(QIODevice::WriteOnly);
    output_bison_file.close();

    QProcess *process;
    process = new QProcess();

    if(OS == "Windows")
    {
        process->start("./start_win.bat"); //запуск анализатора
    }
    if(OS == "Linux")
    {
        process->start("/bin/bash start_linux.sh"); //запуск анализатора
    }
    process->waitForFinished();

    /* создание объектов мира на основе разобранного файла */

    output_bison_file.open(QIODevice::ReadOnly);  
    QTextStream in(&output_bison_file);
    in.setCodec("Windows-1251");

    int x_for_point;
    int y_for_point;

    bool ok;
    QString str,str2,str3;
    QPoint current_point;
    int last_ind,count_of_zones;

    while(1) /* считывание пустых строк оставшихся в файле из-за анализа  возможно потом уберется*/
    {
        str = in.readLine();
        if(str == "BEGIN")
        {
            break;
        }
    }
    while(1)
    {
        str = in.readLine();
        if(str == "END") /* вся информация вычитана */
        {
            break;
        }
        if(str == "мир")
        {
             New_World.Set_GO_Type(str);
             New_World.Set_GO_Name(in.readLine());

             New_World.Set_GO_Width(in.readLine().toInt(&ok,10));
             New_World.Set_GO_Height(in.readLine().toInt(&ok,10));

             x_for_point = in.readLine().toInt(&ok,10);
             y_for_point = in.readLine().toInt(&ok,10);
             current_point.setX(x_for_point);
             current_point.setY(y_for_point);
             New_World.Set_GO_Base_Point(current_point);

             /* считывание координат (имеют смысл только для линейных объектов)*/
             last_ind = in.readLine().toInt(&ok,10);
             for(int i = 0; i <= last_ind; i++)
             {
                 str = in.readLine();
                 QStringList fields = str.split("::",QString::SkipEmptyParts);
                 str2 = fields[0];
                 str3 = fields[1];
                 current_point.setX(str2.toInt(&ok,10));
                 current_point.setY(str3.toInt(&ok,10));
                 New_World.Add_GO_Point(current_point);
             }
             /* считывание информации о заметках */
             count_of_zones = in.readLine().toInt(&ok,10);
             for(int i = 0; i < count_of_zones; i++)
             {
                 Zone New_Zone;
                 New_Zone.Set_Zone_Name(in.readLine());
                 New_World.Add_GO_Zone(New_Zone);
             }
        }
        else
        {          
             GO New_GO;

             New_GO.Set_GO_Type(str);
             New_GO.Set_GO_Name(in.readLine());

             New_GO.Set_GO_Width(in.readLine().toInt(&ok,10));
             New_GO.Set_GO_Height(in.readLine().toInt(&ok,10));

             x_for_point = in.readLine().toInt(&ok,10);
             y_for_point = in.readLine().toInt(&ok,10);
             current_point.setX(x_for_point);
             current_point.setY(y_for_point);
             New_GO.Set_GO_Base_Point(current_point);

             /* считывание координат (имеют смысл только для линейных объектов)*/
             last_ind = in.readLine().toInt(&ok,10);
             for(int i = 0; i <= last_ind; i++)
             {
                 str = in.readLine();
                 QStringList fields = str.split("::",QString::SkipEmptyParts);
                 str2 = fields[0];
                 str3 = fields[1];
                 current_point.setX(str2.toInt(&ok,10));
                 current_point.setY(str3.toInt(&ok,10));
                 New_GO.Add_GO_Point(current_point);     
             }
             /* считывание информации о заметках */
             count_of_zones = in.readLine().toInt(&ok,10);
             for(int i = 0; i < count_of_zones; i++)
             {
                 Zone New_Zone;
                 New_Zone.Set_Zone_Name(in.readLine());
                 New_GO.Add_GO_Zone(New_Zone);
             }
             New_World.Add_GO(New_GO);
         }
   }
   output_bison_file.close();

   Prog_World = New_World;

}
void MainWindow::Menu_Create_World_Function()
{
    ui->Entering_Text->setEnabled(true);
    ui->Button_Create_World->setEnabled(true);
}
void MainWindow::Menu_Open_World_Function()
{
    /*мир уже описан и его описание целиком хранится в текстовом файле*/

    path_of_opened_file = QFileDialog::getOpenFileName(this, "Open text file", ".", "text files *.txt;;");
    
    if(path_of_opened_file == "")
        return;
    
    ui->Combo_Box_GO->clear();

    QFile input_world_file(path_of_opened_file);
    QTextStream in(&input_world_file);
    input_world_file.open(QIODevice::ReadOnly);
    in.setCodec("Windows-1251");
    ui->Entering_Text->setPlainText(in.readAll());
    input_world_file.close();
    
    Create_World_Function(ui->Entering_Text->toPlainText());

    GOs_Combo_Box_Initialization();
    GOs_Notes_Initialization();

    ui->Entering_Text->setEnabled(true);
    ui->Button_Create_World->setEnabled(true);
}
void MainWindow::Menu_Save_World_Function()
{
    if(path_of_opened_file == "")
    {
        Menu_Save_As_World_Function();
    }
    else
    {
        saving(path_of_opened_file);
    }
}
void MainWindow::saving(QString path)
{
     QFile saving_world_file(path);
     saving_world_file.open(QIODevice::WriteOnly);
     QTextStream out(&saving_world_file);
     out << ui->Entering_Text->toPlainText();
     saving_world_file.close();
}
void MainWindow::Menu_Save_As_World_Function()
{
    QString path;
    path = QFileDialog::getSaveFileName(this, "Open text file", ".", "text files *.txt;;");
    saving(path);
}
void MainWindow::Combo_Box_GO_Function()
{
    int i,j;
    ui->Combo_Box_Zones->clear();
    for(i = 0; i < ui->Combo_Box_GO->count(); i++)
    {
        if(Prog_World.Return_GO(i)->Get_GO_Type()+ " " + Prog_World.Return_GO(i)->Get_GO_Name() == ui->Combo_Box_GO->currentText())
        {
            ui->GO_Information_Text->clear();
            ui->Zone_Information_Text->clear();
            ui->GO_Information_Text->append(Prog_World.Return_GO(i)->Get_GO_Notes());
            for(j = 0; j < Prog_World.Return_GO(i)->Return_GO_Zones_Count();j++)
            {
                ui->Combo_Box_Zones->addItem("зона " + Prog_World.Return_GO(i)->Return_GO_Zone(j)->Get_Zone_Name());
            }
            break;
        }
    }
}
void MainWindow::Combo_Box_Zones_Function()
{
    int i,j;
    for(i = 0; i < ui->Combo_Box_GO->count(); i++)
    {
        if(Prog_World.Return_GO(i)->Get_GO_Type()+ " " + Prog_World.Return_GO(i)->Get_GO_Name() == ui->Combo_Box_GO->currentText())
        {
            for(j = 0; j < Prog_World.Return_GO(i)->Return_GO_Zones_Count();j++)
            {
                QString str = ui->Combo_Box_Zones->currentText();
                QString str2 = "зона " + Prog_World.Return_GO(i)->Return_GO_Zone(j)->Get_Zone_Name();
                if(str == str2)
                {
                    ui->Zone_Information_Text->clear();
                    ui->Zone_Information_Text->append(Prog_World.Return_GO(i)->Return_GO_Zone(j)->Get_Zone_Description());
                }
            }
        }
    }
}
void MainWindow::GOs_Combo_Box_Initialization()
{
    int i;
    for(i = 0; i < Prog_World.Return_GOs_Count(); i++)
    {
        ui->Combo_Box_GO->addItem(Prog_World.Return_GO(i)->Get_GO_Type()+ " " + Prog_World.Return_GO(i)->Get_GO_Name());
    }
    ui->Combo_Box_GO->update();
}
void MainWindow::GOs_Notes_Initialization()
{
    int i,j,k;
    QString notes_without_zones;

    Prog_World.Set_GO_Notes(GOs_Notes_Selection(ui->Entering_Text->toPlainText(),Prog_World.Get_GO_Type(),Prog_World.Get_GO_Name(),'"'));
    for(i = 0; i < Prog_World.Return_GOs_Count(); i++)
    {       
        notes_without_zones = "";
        Prog_World.Return_GO(i)->Set_GO_Notes(GOs_Notes_Selection(ui->Entering_Text->toPlainText(),Prog_World.Return_GO(i)->Get_GO_Type(),Prog_World.Return_GO(i)->Get_GO_Name(),'"'));
        for(j = 0; j < Prog_World.Return_GO(i)->Return_GO_Zones_Count(); j++)
        {
            Prog_World.Return_GO(i)->Return_GO_Zone(j)->Set_Zone_Description(GOs_Notes_Selection(Prog_World.Return_GO(i)->Get_GO_Notes(),"зона",Prog_World.Return_GO(i)->Return_GO_Zone(j)->Get_Zone_Name(),'/'));
        }
        /* обрезка зона из заметок */
        for(k = 0; k <  Prog_World.Return_GO(i)->Get_GO_Notes().length() && Prog_World.Return_GO(i)->Get_GO_Notes()[k]!= '/'; k++)
        {
            notes_without_zones += Prog_World.Return_GO(i)->Get_GO_Notes()[k];
        }
        Prog_World.Return_GO(i)->Set_GO_Notes(notes_without_zones);
    }
    /* вывод стартовой информации */
    ui->World_Information_Text->append(Prog_World.Get_GO_Notes());
    if(Prog_World.Return_GOs_Count()!=0)
    {
        ui->GO_Information_Text->append(Prog_World.Return_GO(0)->Get_GO_Notes());
        if(Prog_World.Return_GO_Zones_Count()!=0)
        {
            ui->Zone_Information_Text->append(Prog_World.Return_GO(0)->Return_GO_Zone(0)->Get_Zone_Description());
        }
    }
}
QString MainWindow::GOs_Notes_Selection(QString notes, QString type, QString name, char slash)
{
    /* выделение в заметках текста именно об объекте */
    bool flag_name = false,flag_start = false;
    int count_of_slashes = 0,gaps = 0;
    QString str,cur_name,ret_str,name_without_gaps;
    int start_pos,finish_pos;

    int k;
    str = "";
    cur_name = "";
    ret_str = "";

    for(k = 0; k < name.length();k++)
    {
        if(name[k]!=' ')
        {
            name_without_gaps[k-gaps] = name[k];
        }
        else
        {
            gaps++;
        }
    }
    name = name_without_gaps;

    for(k = 0; k < notes.length(); k++)
    {
        if(notes[k] == slash && count_of_slashes == 0 && flag_start == false)
        {
            flag_name = true;
            count_of_slashes++;
            continue;
        }
        if(notes[k] == slash && count_of_slashes == 0 && flag_start == true )
        {
            finish_pos = k;
            break;
        }
        if(notes[k] == slash && count_of_slashes == 1)
        {
            flag_name = false;         
            count_of_slashes = 0;
            if(cur_name == type + name || cur_name == name + type)
            {
                start_pos = k+1;
                flag_start = true;
            }
            cur_name = "";
        }
        if(flag_name == true)
        {
            if(notes[k] != ' ' && notes[k] != '\n')
            {
                cur_name += notes[k];
            }
        }
        if(k == notes.length()-1)
        {
            finish_pos = notes.length();
        }
    }
    for(k = start_pos; k < finish_pos; k++)
    {
        ret_str +=notes[k];
    }

    return ret_str;
}
